home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK2.toast / Development Kits (Disc 2) / QuickTime Conferencing / Programming Stuff / Sample Code / SeeWorld / Philco.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-23  |  15.8 KB  |  880 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        Philco.c
  3.  
  4.     Contains:    Join in the TV Nation
  5.  
  6.     Written by:    Guy Riddle
  7.  
  8.     Copyright:    © 1994 by Apple Computer, Inc., all rights reserved.
  9.  
  10. */
  11.  
  12. #include <Types.h>
  13. #include <QuickDraw.h>
  14. #include <Fonts.h>
  15. #include <Events.h>
  16. #include <Windows.h>
  17. #include <Menus.h>
  18. #include <Dialogs.h>
  19. #include <Desk.h>
  20. #include <ToolUtils.h>
  21. #include <Memory.h>
  22. #include <SegLoad.h>
  23. #include <Files.h>
  24. #include <Folders.h>
  25. #include <OSUtils.h>
  26. #include <DiskInit.h>
  27. #include <Scrap.h>
  28. #include <Resources.h>
  29. #include <AppleEvents.h>
  30.  
  31. #include <String.h>
  32. #include <Strings.h>
  33. #include <stdio.h>
  34.  
  35. #include <QuickTimeConferencing.h>
  36.  
  37. #include "See.h"
  38.  
  39. typedef    EventRecord            *EventRecordPtr;
  40. typedef    Byte                *BytePtr;
  41. typedef AppleEvent            *AppleEventPtr;
  42.  
  43. #define        PW_CLEAR        'pw-C'    
  44. #define        kMTNameType        'mtnm'
  45. #define        kMTNameListType    'mtnl'
  46.  
  47. typedef struct {
  48.     QElemPtr                qLink;
  49.     Rect                    box;
  50.     MTConferenceMember        member;
  51.     MTControllerComponent    controller;
  52. } Member, *MemberPtr;
  53.  
  54.     Boolean                    gQuitNow;
  55.     QHdr                    gMembers;
  56.                             
  57.     MTCString63                gUserName, gPassword;
  58.     
  59.     ComponentInstance        gCC, gBC;
  60.     
  61.     Rect                    gStandardScreen        = { 100, 100, 220, 260 };
  62.     
  63.     MemberPtr        FindMember(MTConferenceMember);
  64.     MemberPtr        FindMemberWindow(WindowPtr);
  65.     
  66.     void            Initialize(void);
  67.     void            StartMovieTalk(void);
  68.     pascal OSErr    HandleOAPP(AppleEventPtr, AppleEventPtr, long);
  69.     pascal OSErr    HandleODOC(AppleEventPtr, AppleEventPtr, long);
  70.     void            FileCall(FSSpecPtr);
  71.     pascal OSErr    HandleQUIT(AppleEventPtr, AppleEventPtr, long);
  72.     void            StopMovieTalk(void);
  73.     void            EventLoop(void);
  74.     
  75.     void            DoToolboxEvent(EventRecordPtr);
  76.     void            DoKeyDownEvent(EventRecordPtr);
  77.     void            DoMouseDownEvent(EventRecordPtr);
  78.     void            DoDiskEvent(EventRecordPtr);
  79.     void            AdjustMenus(void);
  80.     void            DoMenuBar(long);
  81.     void            DoAppleMenu(short);
  82.     void            DoFileMenu(short);
  83.     void            DoMenuCall(void);
  84.     void            DoMenuHangUp(WindowPtr);
  85.     void            DoMenuSave(int, ResType, WindowPtr);
  86.     void            SaveScreen(WindowPtr);
  87.     
  88.     void            DoConferenceEvent(MTConferenceEventPtr);
  89.     void            DoConfReady(MTConferenceEventPtr);
  90.     void            DoMemberReady(MTConferenceEventPtr);
  91.     void            DoMemberTerminated(MTConferenceEventPtr);
  92.     void            DoPhoneRinging(MTConferenceEventPtr);
  93.     void            DoMemberJoining(MTConferenceEventPtr);
  94.     Boolean            Requires(MTConferenceMember, OSType);
  95.     Handle            GetPassword(Ptr);
  96.     void            EnableButton(DialogRef, short, Boolean);
  97.     void            GetValue(BytePtr, DialogRef, short);
  98.  
  99.     MemberPtr        CallOne(MTNamePtr);
  100.     void            SaveMovie(Handle);
  101.     void            SaveSnapshot(Handle);
  102.     void            Sorry(int, int, MTConferenceMember, OSErr);
  103.     
  104. /*
  105.  *    SeeTV
  106.  *
  107.  *    This conferencing application is receive only.  It doesn't accept incoming calls or transmit
  108.  *    any media data.
  109.  *
  110.  *    • Required Apple Events are supported (well, not printing)
  111.  *
  112.  *    • You can save a "channel setting" to a file which can be double-clicked or dragged to SeeTV
  113.  *    or placed into your Startup Items folder to automatically call someone
  114.  *
  115.  *    • Windows are auto-positioned to avoid overlap
  116.  *
  117.  *    • An arbitary number of calls can be simultaneously handled at once
  118.  *
  119.  *    • Calls are never merged into multi-party conferences
  120.  *
  121.  *    • mtNoAutoResizePrepMask is used to request the windows retain the user-adjusted size instead of
  122.  *    resizing at the whim of the sender
  123.  */
  124.  
  125. void main()
  126. {
  127.     Initialize();
  128.     EventLoop();
  129.     StopMovieTalk();
  130. }
  131.  
  132.     void 
  133. Initialize(
  134.     void
  135. ){
  136.     Handle                    menuBar;
  137.  
  138.     InitGraf((Ptr) &qd.thePort);
  139.     InitFonts();
  140.     InitWindows();
  141.     InitMenus();
  142.     TEInit();
  143.     InitDialogs(nil);
  144.     InitCursor();
  145.             
  146.     StartMovieTalk();
  147.  
  148.     menuBar = GetNewMBar(rPhilcoMenuBar);
  149.  
  150.     SetMenuBar(menuBar);
  151.     DisposHandle(menuBar);
  152.     AddResMenu(GetMHandle(mApple), 'DRVR');
  153.  
  154.     DrawMenuBar();
  155.     
  156.     AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, NewAEEventHandlerProc(HandleOAPP), 0, false);
  157.     AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, NewAEEventHandlerProc(HandleODOC), 0, false);
  158.     AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerProc(HandleQUIT), 0, false);
  159. }
  160.  
  161.     void
  162. StartMovieTalk(
  163.     void
  164. ){
  165.     StringHandle            sh;
  166.  
  167.     sh = GetString(kMTAppleTalkUserName);
  168.     
  169.     strncpy((char*)gUserName, (char*)*sh+1, **sh);
  170.     
  171.     gCC = OpenDefaultComponent(kMTConferenceType, kMTMovieTalkSubType);
  172.     
  173.     MTConferenceSetMode(gCC, mtReceiveMediaModeMask);
  174.     MTConferenceSetDefaultWindowProcID(gCC, zoomDocProc);
  175.     
  176.     MTConferenceListen(gCC, gUserName, gUserName, (MTCString)"mtlkatlk\tNoIncomingCalls\x0Dmtlktcpi\t606\x0Dmtlkisdn\t-\x0D");
  177.     
  178.     gBC = OpenDefaultComponent(kMTBrowserType, kMTAppleTalkSubType);
  179. }
  180.  
  181.     pascal OSErr
  182. HandleOAPP(
  183.     AppleEventPtr            /* unused */,
  184.     AppleEventPtr            /* unused */,
  185.     long                    /* unused */
  186. ){
  187.     return(noErr);
  188. }
  189.  
  190.     pascal OSErr
  191. HandleODOC(
  192.     AppleEventPtr            aev,
  193.     AppleEventPtr            /* unused */,
  194.     long                    /* unused */
  195. ){
  196.     AEDescList                docs;
  197.     long                    n, count;
  198.     AEKeyword                key;
  199.     FSSpec                    fss;
  200.     DescType                type;
  201.     Size                    size;
  202.     OSErr                    err;
  203.     
  204.     if(err = AEGetParamDesc(aev, keyDirectObject, typeAEList, &docs))
  205.         return(err);
  206.         
  207.     AECountItems(&docs, &count);
  208.     
  209.     for(n = 1; n <= count; n++)
  210.         if(err = AEGetNthPtr(&docs, n, typeFSS, &key, &type, &fss, sizeof(FSSpec), &size))
  211.             break;
  212.         else
  213.             FileCall(&fss);
  214.             
  215.     AEDisposeDesc(&docs);
  216.     
  217.     return(err);
  218. }
  219.  
  220.     void
  221. FileCall(
  222.     FSSpecPtr                fs
  223. ){
  224.     int                        n, count;
  225.     Handle                    h;
  226.     MemberPtr                mp;
  227.     short                    id, refnum;
  228.     ResType                    type;
  229.     Str255                    name;
  230.     
  231.     if(!(refnum = FSpOpenResFile(fs, fsRdPerm)))
  232.         return;
  233.         
  234.     count = Count1Resources(kMTNameType);
  235.     
  236.     for(n = 1; n <= count; n++){
  237.         h = Get1IndResource(kMTNameType, n);
  238.         HLock(h);
  239.         
  240.         mp = CallOne((MTNamePtr) *h);
  241.         
  242.         GetResInfo(h, &id, &type, name);
  243.         
  244.         if(h = Get1Resource('RECT', id))
  245.             mp->box = *(RectPtr) (*h);
  246.     }
  247.     
  248.     CloseResFile(refnum);
  249. }
  250.  
  251.     pascal OSErr
  252. HandleQUIT(
  253.     AppleEventPtr            /* unused */,
  254.     AppleEventPtr            /* unused */,
  255.     long                    /* unused */
  256. ){
  257.     gQuitNow = true;
  258.     
  259.     return(noErr);
  260. }
  261.  
  262.     void
  263. EventLoop(
  264.     void
  265. ){
  266.     EventRecord                tEvent;
  267.     MTConferenceEvent        cEvent;
  268.  
  269.     for(; !gQuitNow;){
  270.         if(MTConferenceGetNextEvent(gCC, &cEvent))
  271.             DoConferenceEvent(&cEvent);
  272.             
  273.         if(WaitNextEvent(everyEvent, &tEvent, 1, 0))
  274.             DoToolboxEvent(&tEvent);
  275.     }
  276. }
  277.  
  278.     void
  279. DoToolboxEvent(
  280.     EventRecordPtr            ev
  281. ){
  282.     switch(ev->what) {
  283.     case mouseDown:
  284.         DoMouseDownEvent(ev);
  285.         break;
  286.     
  287.     case keyDown:
  288.         DoKeyDownEvent(ev);
  289.         break;
  290.         
  291.     case kHighLevelEvent:
  292.         AEProcessAppleEvent(ev);
  293.         break;
  294.     
  295.     case diskEvt:
  296.         DoDiskEvent(ev);
  297.     }
  298. }
  299.  
  300.     void
  301. DoMouseDownEvent(
  302.     EventRecordPtr            ev
  303. ){
  304.     WindowPtr                wp;
  305.     short                    part;
  306.     
  307.     part = FindWindow(ev->where, &wp);
  308.     
  309.     switch(part){
  310.     case inMenuBar:
  311.         AdjustMenus();
  312.         DoMenuBar(MenuSelect(ev->where));
  313.     }
  314. }
  315.  
  316.     void
  317. DoKeyDownEvent(
  318.     EventRecordPtr            ev
  319. ){
  320.     if(ev->modifiers & cmdKey){
  321.         AdjustMenus();    
  322.         DoMenuBar(MenuKey(ev->message & charCodeMask));
  323.     }
  324. }
  325.  
  326.     void
  327. DoDiskEvent(
  328.     EventRecordPtr            ev
  329. ){
  330.     Point                    where;
  331.  
  332.     if(HiWord(ev->message)){
  333.         SetPt(&where, kDILeft, kDITop);
  334.         DIBadMount(where, ev->message);
  335.     }
  336. }
  337.  
  338.     void
  339. AdjustMenus(
  340.     void
  341. ){
  342.     MenuHandle                mh;
  343.     
  344.     mh = GetMHandle(mtFile);
  345.     
  346.     if(FrontWindow()){
  347.         EnableItem(mh, itClose);
  348.         EnableItem(mh, itSave);
  349.         EnableItem(mh, itSaveAll);
  350.     }else{
  351.         DisableItem(mh, itClose);
  352.         DisableItem(mh, itSave);
  353.         DisableItem(mh, itSaveAll);
  354.     }
  355. }
  356.  
  357.     void
  358. DoMenuBar(
  359.     long                    selection
  360. ){
  361.     short                    menuID;    
  362.     short                    menuItem;
  363.  
  364.     menuID = HiWord(selection);
  365.     menuItem = LoWord(selection);
  366.     
  367.     switch(menuID){
  368.     case mApple:
  369.         DoAppleMenu(menuItem);
  370.         break;
  371.         
  372.     case mtFile:
  373.         DoFileMenu(menuItem);
  374.         break;
  375.         
  376.     case mEdit:                    /* call SystemEdit for DA editing & MultiFinder */
  377.         SystemEdit(menuItem-1);
  378.     }
  379.     
  380.     HiliteMenu(0);
  381. }
  382.  
  383.     void
  384. DoAppleMenu(
  385.     short                    item
  386. ){
  387.     DialogRef                dp;
  388.     Str255                    daName;
  389.     short                    itemHit;
  390.  
  391.     switch(item){
  392.     case iAbout:
  393.         dp = GetNewDialog(rAboutAlert, nil, (WindowRef) -1);
  394.         SetDialogDefaultItem(dp, 1);
  395.         
  396.         ModalDialog(0, &itemHit);
  397.         
  398.         DisposeDialog(dp);
  399.         break;
  400.         
  401.     default:            /* all non-About items in this menu are DAs */
  402.         GetItem(GetMHandle(mApple), item, daName);
  403.         OpenDeskAcc(daName);
  404.     }
  405. }
  406.  
  407.     void
  408. DoFileMenu(
  409.     short                    item
  410. ){
  411.     switch(item){
  412.     case itNew:
  413.         DoMenuCall();
  414.         break;
  415.     
  416.     case itClose:
  417.         DoMenuHangUp(FrontWindow());
  418.         break;
  419.         
  420.     case itSave:
  421.         DoMenuSave(1, kMTNameType, FrontWindow());
  422.         break;
  423.         
  424.     case itSaveAll:
  425.         DoMenuSave(2, kMTNameListType, 0);
  426.         break;
  427.         
  428.     case itQuit:
  429.         gQuitNow = true;
  430.     }
  431. }
  432.  
  433.     void
  434. StopMovieTalk(
  435.     void
  436. ){
  437.     CloseComponent(gCC);
  438.     CloseComponent(gBC);
  439. }
  440.  
  441.     void
  442. DoMenuCall(
  443.     void
  444. ){
  445.     MTNameListPtr            names;
  446.     MTNamePtr                np;
  447.     int                        count;
  448.     ComponentResult            err;
  449.     
  450.     err = MTBrowserBrowse(gBC, 0,"\pLets Tune In…", (MTCString)"mtlkatlk\tMulticaster\x0D", 0, &names);
  451.     
  452.     if(err)
  453.         return;
  454.         
  455.     count = GetMTNameListCount(names);
  456.     np = &(names->list[0]);
  457.  
  458.     while(--count >= 0)
  459.         CallOne(np++);
  460.         
  461.     DisposeMTNameList(names);
  462. }
  463.  
  464.     MemberPtr
  465. CallOne(
  466.     MTNamePtr                np
  467. ){
  468.     MemberPtr                mp;
  469.     
  470.     if(!(mp = FindMember(0)))
  471.         return(0);
  472.  
  473.     mp->member = MTConferenceCall(gCC, (MTCString)"TV Nation", np);
  474.     mp->box = gStandardScreen;
  475.     
  476.     return(mp);
  477. }
  478.  
  479.     void
  480. DoMenuHangUp(
  481.     WindowPtr                wp
  482. ){
  483.     MemberPtr                mp;
  484.     
  485.     if(mp = FindMemberWindow(wp))
  486.         MTConferenceTerminate(gCC, MTConferenceGetMemberConference(gCC, mp->member));
  487. }
  488.  
  489.     void
  490. DoMenuSave(
  491.     int                        note,
  492.     ResType                    filetype,
  493.     WindowPtr                wp
  494. ){
  495.     Handle                    h;
  496.     short                    refnum;
  497.     StandardFileReply        reply;
  498.     Str255                    prompt, name;
  499.     
  500.     GetIndString(prompt, 401, note);
  501.     
  502.     if(wp)
  503.         GetWTitle(wp, name);
  504.     else
  505.         GetIndString(name, 402, note);
  506.         
  507.     StandardPutFile(prompt, name, &reply);
  508.     
  509.     if(!reply.sfGood)
  510.         return;
  511.         
  512.     if(reply.sfReplacing)
  513.         FSpDelete(&reply.sfFile);
  514.         
  515.     FSpCreateResFile(&reply.sfFile, 'SW•6', filetype, reply.sfScript);
  516.     if(!(refnum = FSpOpenResFile(&reply.sfFile, fsRdWrPerm)))
  517.         return;
  518.     
  519.     if(wp)
  520.         SaveScreen(wp);
  521.     else
  522.         for(wp = FrontWindow(); wp; wp = (WindowPtr) ((WindowPeek) wp)->nextWindow)
  523.             SaveScreen(wp);
  524.             
  525.     h = GetResource('STR ', -16396);
  526.     DetachResource(h);
  527.     AddResource(h, 'STR ', -16396, "\p");
  528.     
  529.     CloseResFile(refnum);
  530. }
  531.  
  532.     void
  533. SaveScreen(
  534.     WindowPtr                wp
  535. ){
  536.     MTNameListPtr            nl;
  537.     MemberPtr                mp;
  538.     Handle                    h;
  539.     short                    id;
  540.     Rect                    box;
  541.     
  542.     if(!(mp = FindMemberWindow(wp)))
  543.         return;
  544.         
  545.     nl = MTConferenceGetReturnAddress(gCC, mp->member);
  546.     PtrToHand((Ptr) nl->list, &h, sizeof(MTName));
  547.     DisposeMTNameList(nl);
  548.     
  549.     id = UniqueID(kMTNameType);
  550.     
  551.     AddResource(h, kMTNameType, id, "\p");
  552.     
  553.     SetPort(wp);
  554.     box = wp->portRect;
  555.     LocalToGlobal((PointPtr) &box.top);
  556.     LocalToGlobal((PointPtr) &box.bottom);
  557.     box.bottom -= 16;
  558.     
  559.     PtrToHand((Ptr) &box, &h, sizeof(Rect));
  560.     AddResource(h, 'RECT', id, "\p");
  561. }
  562.  
  563.     void
  564. DoConferenceEvent(
  565.     MTConferenceEventPtr    ce
  566. ){
  567.     switch(ce->what){
  568.     case mtConferenceReadyEvent:
  569.         DoConfReady(ce);
  570.         break;
  571.     
  572.     case mtMemberReadyEvent:
  573.         DoMemberReady(ce);
  574.         break;
  575.     
  576.     case mtMemberTerminatedEvent:
  577.         DoMemberTerminated(ce);
  578.         break;
  579.     
  580.     case mtMemberJoiningEvent:
  581.         DoMemberJoining(ce);
  582.         break;
  583.         
  584.     case mtPhoneRingingEvent:
  585.         DoPhoneRinging(ce);
  586.         break;
  587.     
  588.     case mtRefusedEvent:
  589.         Sorry(701, 1, ce->who, ce->err);
  590.         break;
  591.     
  592.     case mtFailedEvent:
  593.         Sorry(701, 2, ce->who, ce->err);
  594.         break;
  595.         
  596.     case mtSnapshotTakenEvent:
  597.         SaveSnapshot(ce->surprise);
  598.         break;
  599.         
  600.     case mtMovieRecordedEvent:
  601.         SaveMovie(ce->surprise);
  602.     }
  603.     
  604.     if(ce->surprise)
  605.         DisposeHandle(ce->surprise);
  606. }
  607.  
  608.     void
  609. DoMemberJoining(
  610.     MTConferenceEventPtr    ce
  611. ){
  612.     MemberPtr                mp;
  613.     
  614.     if(mp = FindMember(0))
  615.         mp->member = ce->who;
  616.     else
  617.         Sorry(702, 2, ce->who, 0);
  618. }
  619.  
  620.     void
  621. DoConfReady(
  622.     MTConferenceEventPtr    ce
  623. ){
  624.     MTConferenceActivateConference(gCC, ce->who, 0);
  625. }
  626.  
  627.     void
  628. DoMemberReady(
  629.     MTConferenceEventPtr    ce
  630. ){
  631.     MemberPtr                mp;
  632.     MTControllerComponent    mtc;
  633.     
  634.     
  635.     if(ce->bonus & mtReceiveMediaModeMask){    
  636.         if(!(mp = FindMember(ce->who)))
  637.             return;
  638.     
  639.         mtc = MTConferenceNewPreparedController(gCC, &mp->box,
  640.                mtAutoPositionPrepMask+mtNoAutoResizePrepMask+mtAuxiliaryClosePrepMask+mtWindowVisiblePrepMask+mtControllerVisiblePrepMask+mtEnableSnapshotPrepMask+mtEnableRecordPrepMask,
  641.                MTConferenceGetMemberName(gCC, mp->member));
  642.                
  643.         mp->controller = mtc;
  644.     }else
  645.         mtc = 0;
  646.                        
  647.     MTConferenceActivateMember(gCC, ce->who, mtc);
  648. }
  649.  
  650.     void
  651. DoMemberTerminated(
  652.     MTConferenceEventPtr    ce
  653. ){
  654.     MemberPtr                mp;
  655.     
  656.     if(!(mp = FindMember(ce->who)))
  657.         return;
  658.         
  659.     if(mp->controller)
  660.         MTConferenceDisposeController(gCC, mp->controller);
  661.         
  662.     Dequeue((QElemPtr) mp, &gMembers);
  663.     DisposePtr((Ptr) mp);
  664. }
  665.  
  666.     void
  667. DoPhoneRinging(
  668.     MTConferenceEventPtr    ce
  669. ){
  670.     Handle                    ph;
  671.     
  672.     if((ce->bonus & mtRequiredMessagesModeMask) && Requires(ce->who, PW_CLEAR) && (ph = GetPassword((Ptr)MTConferenceGetMemberName(gCC, ce->who))))
  673.         MTConferenceSendMessageToMember(gCC, ce->who, ph, PW_CLEAR, 1);
  674. }
  675.  
  676.     Boolean
  677. Requires(
  678.     MTConferenceMember        who,
  679.     OSType                    type
  680. ){
  681.     MTCapabilitiesHandle    ch;
  682.     MTCapabilitiesPtr        cp;
  683.     int                        n;
  684.     
  685.     ch = MTConferenceGetMemberMessageCapabilities(gCC, who);
  686.     
  687.     for(n = (*ch)->count, cp = (*ch)->capability; --n >= 0; cp++)
  688.         if(type == cp->messageType && cp->desires == mtMessageRequiredCapability){
  689.             DisposeHandle((Handle) ch);
  690.             return(true);
  691.         }
  692.     
  693.     DisposeHandle((Handle) ch);
  694.     return(false);
  695. }
  696.  
  697.     Handle
  698. GetPassword(
  699.     Ptr                        name
  700. ){
  701.     DialogRef                dp;
  702.     short                    itemHit;
  703.     Handle                    ph;
  704.     char                    p1[255];
  705.     
  706.     if(AEInteractWithUser(20*60, 0, 0))
  707.         return(0);
  708.     
  709.     ParamText(nil, c2pstr(strcpy(p1, name)), nil, nil);
  710.     gPassword[0] = 0;
  711.     
  712.     dp = GetNewDialog(rPassword, 0, (WindowRef) -1);
  713.     SetDialogDefaultItem(dp, diOK);
  714.     SetDialogCancelItem(dp, diCancel);
  715.     SetDialogTracksCursor(dp, true);
  716.     PostEvent(keyDown, '\b');        // ick
  717.     
  718.     do{
  719.         EnableButton(dp, diOK, gPassword[0]);
  720.         
  721.         ModalDialog(0, &itemHit);
  722.         
  723.         GetValue(gPassword, dp, diPassword);
  724.     }while(itemHit > diCancel);
  725.     
  726.     DisposeDialog(dp);
  727.     InitCursor();
  728.     
  729.     if(itemHit == diCancel)
  730.         return(0);
  731.     
  732.     PtrToHand(gPassword, &ph, strlen((char*)gPassword)+1);
  733.     
  734.     return(ph);
  735. }
  736.  
  737.     void
  738. EnableButton(
  739.     DialogRef                dp,
  740.     short                    item,
  741.     Boolean                    enabled
  742. ){
  743.     Handle                    ih;
  744.     Rect                    rect;
  745.     short                    type;
  746.     
  747.     GetDialogItem(dp, item, &type, &ih, &rect);
  748.     
  749.     if(enabled)
  750.         type &= ~itemDisable;
  751.     else
  752.         type |= itemDisable;
  753.         
  754.     HiliteControl((ControlHandle) ih, enabled ? 0 : 255);
  755.     
  756.     SetDialogItem(dp, item, type, ih, &rect);
  757.     
  758.     SetPort(dp);
  759.     InsetRect(&rect, -5, -5);
  760.     InvalRect(&rect);
  761. }
  762.  
  763.     void
  764. GetValue(
  765.     BytePtr                    p,
  766.     DialogRef                dp,
  767.     short                    item
  768. ){
  769.     Handle                    ih;
  770.     Rect                    rect;
  771.     short                    type;
  772.     
  773.     GetDialogItem(dp, item, &type, &ih, &rect);
  774.     GetDialogItemText(ih, p);
  775.     
  776.     if(p[0] && p[p[0]] < ' '){
  777.         p[0]--;            // strip CR or other junk
  778.         SetDialogItemText(ih, p);
  779.     }
  780.     
  781.     p2cstr(p);
  782. }
  783.  
  784.     void
  785. SaveSnapshot(
  786.     Handle                    pic
  787. ){
  788.     ZeroScrap();
  789.     
  790.     HLock(pic);
  791.     
  792.     PutScrap(GetHandleSize(pic), 'PICT', *pic);
  793. }
  794.  
  795.     void
  796. SaveMovie(
  797.     Handle                    h
  798. ){
  799.     Ptr                        p;
  800.     int                        i;
  801.     long                    dirid;
  802.     short                    vrefnum;
  803.     FSSpecPtr                temp;
  804.     FSSpec                    spec;
  805.     Str255                    newname;
  806.     
  807.     HLock(h);
  808.     temp =(FSSpecPtr) *h;
  809.     
  810.     FindFolder(kOnSystemDisk, kDesktopFolderType, true, &vrefnum, &dirid);
  811.     FSMakeFSSpec(vrefnum, dirid, "\p", &spec);
  812.     FSpCatMove(temp, &spec);        // move it to the desktop
  813.     
  814.     FSMakeFSSpec(vrefnum, dirid, temp->name, &spec);
  815.     GetIndString(newname, rWildSTRs, srMovieName);
  816.     p = strchr((char*)newname, '?');
  817.     
  818.     for(i = 1; i < 10; i++){
  819.         *p = '0'+i;
  820.         
  821.         if(FSpRename(&spec, newname) == noErr)
  822.             return;                    // and give it a better name
  823.     }
  824.     
  825.     SysBeep(1);
  826. }
  827.     
  828.     MemberPtr
  829. FindMember(
  830.     MTConferenceMember        who
  831. ){
  832.     MemberPtr                mp;
  833.  
  834.     if(who){
  835.         for(mp = (MemberPtr) gMembers.qHead; mp; mp = (MemberPtr) mp->qLink)
  836.             if(who == mp->member)
  837.                 return(mp);
  838.     }else if(mp = (MemberPtr) NewPtrClear(sizeof(Member)))
  839.         Enqueue((QElemPtr) mp, &gMembers);
  840.         
  841.     return(mp);
  842. }
  843.     
  844.     MemberPtr
  845. FindMemberWindow(
  846.     WindowPtr                wp
  847. ){
  848.     MemberPtr                mp;
  849.     MTControllerComponent    mtc;
  850.     
  851.     mtc = (MTControllerComponent) GetWRefCon(wp);
  852.  
  853.     for(mp = (MemberPtr) gMembers.qHead; mp; mp = (MemberPtr) mp->qLink)
  854.         if(mtc == mp->controller)
  855.             break;
  856.         
  857.     return(mp);
  858. }
  859.  
  860.     void
  861. Sorry(
  862.     int                        why,
  863.     int                        note,
  864.     MTConferenceMember        who,
  865.     OSErr                    err
  866. ){
  867.     Str255                    p1, p2, p3;
  868.     
  869.     if(AEInteractWithUser(20*60, 0, 0))
  870.         return;
  871.     
  872.     GetIndString(p1, why, note);
  873.     
  874.     strcpy((char*)p2, (char*)MTConferenceGetMemberName(gCC, who));
  875.     sprintf((char*)p3, "%d", err);
  876.     
  877.     ParamText(nil, p1, c2pstr((char*)p2), c2pstr((char*)p3));
  878.     
  879.     CautionAlert(why, 0);
  880. }